package rmi.domain;

import java.io.IOException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import org.apache.log4j.*;

/*
 * Creates exactly one registry per host (even by multiple VMs)
 * If a registry on the transferred port already exists it will be validated. 
 * The registry reference will be given back after a positive validation test
 *
 */


public class RegistrySingleton {
	private static Logger log = Logger.getLogger(RegistrySingleton.class);
	private static Registry reg =null;
	private static String registryHost="";
	private static int port=0;
	
	
	public static Registry initialRegistry (){
			readProperties();	
			//check if there is an existing registry
		 	if (reuseRegistry(port)) {
	            log.debug("return existing registry on port " + port);
	            return reg;
	        //try to create new registry
	        } else {
	        	if (createNewRegistry(port)) {
	        
	        	log.debug("return new registry on " + port);
	            return reg;
	        	}
	        }
	        // fail:
		 	//reg=null
	        return reg;
	}
	
	//reuse registry
	private static boolean reuseRegistry(int port) {
		 Registry registry = null;
	        try {
	        	log.debug("Try get get existing Registry");
	        	registry = LocateRegistry.getRegistry(registryHost,port);
	            return checkRegistry(registry);

	        } catch (RemoteException e) {
	            log.debug("Error getting existing registry, maybe no registry exists. Trying to create a new one");
	        }
	        return false;
	}
	
	//Create new registry
	private static boolean createNewRegistry(int port) {
		try {
            Registry registry = LocateRegistry.createRegistry(port);
            log.info("New Registry on port "+port+" was created.");
            return checkRegistry(registry);

        } catch (RemoteException e) {
        	log.error("Error creating new registry: "+e.getMessage());
            return false;
        }

   
	}
	
	//validation of registry
	private static boolean checkRegistry(Registry registry) {
		 if (registry != null) {
	          
	            try {
	                String[] objectsRemote = registry.list();

	                for (String o : objectsRemote) {
	                    log.debug("object available in registry: "+o );
	                }
	                log.debug("Registry is valid!");
	                reg = registry;
	                return true;

	            } catch (RemoteException ex) {
	            	log.debug("Registry is invalid: "+ex.getMessage());
	            	return false;
	            }
	           
	        }
	        
		  return false;
    }
	private static void readProperties(){
		java.io.InputStream is = ClassLoader.getSystemResourceAsStream("registry.properties");
		if (is != null) {
			java.util.Properties props = new java.util.Properties();
			try {
				props.load(is);
				registryHost = props.getProperty("registry.host");
				port = Integer.valueOf(props.getProperty("registry.port"));
				
			} catch (IOException e) {
				log.debug("Error Reading Properties");
			} finally {
				try {
					is.close();
				} catch (IOException e) {
					log.debug("Error Reading Properties");
				}
			}
		} else {
			System.err.println("Properties file not found!");
		}
	}
	
	
}
